package com.thinkit.bigdata.core.util.bean;

import com.thinkit.bigdata.core.util.StringUtil;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

public class BeanUtils {
	
	/**
	 * 新对象 更新旧对象
	 * 1、新对象属性值不为null，更新旧对象对应的属性值
	 * 2、新对象属性值为null，旧对象对应的属性值不变
	 * @param existObj
	 * @param newObj
	 * @param primKey 实体类对应的数据库主键
	 */
	public static Object copyProperties(Object existObj,Object newObj,String primKey){
		if(existObj==null || newObj==null || "".equals(StringUtil.null2String(primKey))){
			return null;
		}
		String getPrimKeyMethod="get"+(primKey.charAt(0)+"").toUpperCase()+primKey.substring(1);
		
		Method[] newObjMethods = newObj.getClass().getMethods();
		for (Method newObjMethod : newObjMethods) {
			String getMethodName = newObjMethod.getName();
			//if (getMethodName.indexOf("get") >= 0 && getMethodName.indexOf("Class") == -1 && !getMethodName.equals(getPrimKeyMethod)) {
			if (getMethodName.indexOf("get") >= 0  && !getMethodName.equals(getPrimKeyMethod)&&getMethodName.indexOf("Class") != -1&&getMethodName.indexOf("getClassNo")!=-1) {//针对视频的classno属性
						try {
							Object methodValue = newObjMethod.invoke(newObj);
							if (methodValue != null) {
								String setMethodName = "s" + getMethodName.substring(1);

								for (Method newObjMethod2 : newObjMethods) {
									if (setMethodName.equals(newObjMethod2.getName())) {
										newObjMethod2.invoke(existObj, methodValue);
									}
								}
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					}else if(getMethodName.indexOf("get") >= 0 && getMethodName.indexOf("Class") == -1 && !getMethodName.equals(getPrimKeyMethod)){
						try {
							Object methodValue = newObjMethod.invoke(newObj);
							if (methodValue != null) {
								String setMethodName = "s" + getMethodName.substring(1);

								for (Method newObjMethod2 : newObjMethods) {
									if (setMethodName.equals(newObjMethod2.getName())) {
										newObjMethod2.invoke(existObj, methodValue);
									}
								}
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					}


		}
		return existObj;
	}


	/**
	 * 对象转字节流
	 * @param obj
	 * @return
	 */
	public static byte[] object2Bytes(Object obj){
		byte[] bytes=null;
		try {
			ByteArrayOutputStream bo=new ByteArrayOutputStream();
			ObjectOutputStream os=new ObjectOutputStream(bo);
			os.writeObject(obj);
			bytes=bo.toByteArray();
			bo.close();
			os.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bytes;
	}

	/**
	 * 流转对象
	 * @param bytes
	 * @return
	 */
	public static Object bytes2Object(byte[] bytes){

		if(bytes==null || bytes.length==0){
			return null;
		}
		Object obj=null;
		try {
			ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
			ObjectInputStream oi = new ObjectInputStream(bi);

			obj=oi.readObject();

			bi.close();
			oi.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * Map转成实体对象
	 * @param map map实体对象包含属性
	 * @param clazz 实体对象类型
	 * @return
	 */
	public static Object map2Object(Map<String, Object> map, Class<?> clazz) {
		if (map == null) {
			return null;
		}
		Object obj = null;
		try {
			obj = clazz.newInstance();

			Field[] fields = obj.getClass().getDeclaredFields();
			for (Field field : fields) {
				int mod = field.getModifiers();
				if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
					continue;
				}
				field.setAccessible(true);
				field.set(obj, map.get(field.getName()));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * 实体对象转成Map
	 * @param obj 实体对象
	 * @return
	 */
	public static Map<String, Object> object2Map(Object obj) {
		Map<String, Object> map = new HashMap<>();
		if (obj == null) {
			return map;
		}
		Class clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		try {
			for (Field field : fields) {
				field.setAccessible(true);
				map.put(field.getName(), field.get(obj));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}

}
